# -*- coding: utf-8 -*-

'''
/**
 * @addtogroup msg_hj1239
 * msg_hj1239
 * @{
 */
/**
 * @file        msg_hj1239.py
 * @brief       XXXX
 * @note        XXXX
 * @author      靳普诏(puzhao.jin@hopechart.com)
 * @date        2023/09/23
 * @version     1.0

 * @par         修改日志
 * <table>
 * <tr><th>Date         <th>Version     <th>Author      <th> Description
 * <tr><td>2023/09/23   <td>1.0         <td>靳普诏       <td> 创建初始版本
 * @copyright   xxxx
 */
'''

import sys
import os
import struct 
import copy

def Slice(item, pos:int, len:int):
    return item[pos : pos+len]
    # return copy.deepcopy(item[pos : pos+len])

def CalcCrc(data: bytes):
    crc = 0
    for i in data:
        val = int(i)
        crc = crc ^ val
    return crc & 0xff

def EncodeUInt8(val: int):
    valid = True
    ret = b''
    if val < 0 or val > 0xff:
        valid = False
    else:
        ret = struct.pack(">B", val)
    return valid, ret

def EncodeUInt16(val: int):
    valid = True
    ret = b''
    if val < 0 or val > 0xffff:
        valid = False
    else:
        ret = struct.pack(">H", val)
    return valid, ret


class TMsgHj1239:
    def __init__(self) -> None:
        self.__begin_flag = "##".encode()
        self.__cmd_unit = b''
        self.__vin = b''
        self.__term_version = b''
        self.__encryption_type = b''
        self.__data_unit_len = b''
        self.__data_unit = b''
        self.__crc = b''

    def SetCmdUnit(self, cmd: int):
        valid, self.__cmd_unit = EncodeUInt8(cmd)
        return valid
    def GetCmdUnit(self):
        val = 0xff
        if len(self.__cmd_unit) == 1:
            val = struct.unpack(">B", self.__cmd_unit)[0]
        return val

    def SetVin(self, vin: str):
        valid = True
        if len(vin) != 17:
            valid = False
        else:
            self.__vin = struct.pack(">17s", vin)
        return valid
    def GetVin(self):
        val = ""
        if len(self.__vin) == 17:
            val = struct.unpack(">17s", self.__vin)[0]
        return val
    
    def SetTermVersion(self, val: int):
        valid, self.__term_version = EncodeUInt8(val)
        return valid
    def GetTermVersion(self):
        val = 0xff
        if len(self.__term_version) == 1:
            val = struct.unpack(">B", self.__term_version)[0]
        return val

    def SetEncryptionType(self, val: int):
        valid, self.__encryption_type = EncodeUInt8(val)
        return valid
    def GetEncryptionType(self):
        val = 0xff
        if len(self.__encryption_type) == 1:
            val = struct.unpack(">B", self.__encryption_type)[0]
        return val

    def SetDataUnitLen(self, val: int):
        valid, self.__data_unit_len = EncodeUInt16(val)
        return valid
    def GetDataUnitLen(self):
        val = 0xffff
        if len(self.__data_unit_len) == 2:
            val = struct.unpack(">H", self.__data_unit_len)[0]
        return val

    def SetDataUnit(self, val: bytes):
        valid = self.SetDataUnitLen(len(val))
        if valid:
            self.__data_unit = val
        return valid
    def GetDataUnit(self):
        return self.__data_unit

    def SetCrc(self, val: int):
        valid, self.__crc = EncodeUInt8(val)
        return valid
    def GetCrc(self):
        val = 0xff
        if len(self.__crc) == 1:
            val = struct.unpack(">B", self.__crc)[0]
        return val

    '''
    解码
    param self
    return 
    '''
    def Decode(self, code: bytes):
        limt = 2 + 1 + 17 + 1 + 1 + 2 + 1
        if code.__len__() < limt:
            return False
        pos = 0

        ## 起始符判断
        len = 2
        item = Slice(code, pos, len)
        if item != b"##":
            return False
        pos += len

        ## 命令单元
        len = 1
        item = Slice(code, pos, len)
        self.__cmd_unit = item
        pos += len

        ## 车辆vin
        len = 17
        item = Slice(code, pos, len)
        self.__vin = item
        pos += len

        ## 终端软件版本号
        len = 1
        item = Slice(code, pos, len)
        self.__term_version = item
        pos += len

        ## 数据加密方式
        len = 1
        item = Slice(code, pos, len)
        self.__encryption_type = item
        pos += len

        ## 数据单元长度
        len = 2
        item = Slice(code, pos, len)
        self.__data_unit_len = item
        pos += len

        ## 数据单元
        len = code.__len__() - pos - 1
        data_unit_len = self.GetDataUnitLen()
        if (len != data_unit_len):
            return False
        item = Slice(code, pos, len)
        self.__data_unit = item
        pos += len

        ## 校验码
        crc = CalcCrc(code[2 : -1])
        print(f"crc:{hex(crc)}")
        if crc != int(code[-1]):
            return False
        self.SetCrc(crc)

        return True

    '''
    编码
    param self
    return 
    '''
    def Encode(self):
        valid = True
        code = b''
        # code += self.__begin_flag
        code += self.__cmd_unit
        code += self.__vin
        code += self.__term_version
        code += self.__encryption_type
        code += self.__data_unit_len
        code += self.__data_unit
        valid = self.SetCrc(CalcCrc(code))
        code = self.__begin_flag + code + self.__crc

        if valid:
            self.__code = code
        else:
            code = b''

        return code
    
        


if __name__ == "__main__":
    ## 获取当前脚本所在的目录
    SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
    # 输出目录路径
    print("SCRIPT_DIR: "+ SCRIPT_DIR)

    ## 获取脚本传参
    argv = sys.argv
    argc = len(argv)
    # 打印命令行参数
    #for i in range(1, argc):
        #print("参数", i, ":", argv[i])
        
    print("============= BIGEN: msg_hj1239.py =============")

    chr = b'\x16'
    print(chr[0])
    print(ord(chr))
    print(len(chr))

    chr = b'\x01\x02\x03'
    crc = CalcCrc(chr)
    print(f"crc:{crc}")
    print(chr[0 : 2])

    def Func():
        return 1, 2

    a, b = Func()
    print(a)


    print("============= END: msg_hj1239.py =============")



## Generated on "2023-09-23 14:52:09" by the tool "gen_hq_file.py >> V20230509_1" 